package org.tlipoca.smcomment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.genntii.smcommon.constant.ExceptionConstant;
import org.genntii.smcommon.exception.ArticleNotFoundException;
import org.genntii.smcommon.exception.CommentNotFoundException;
import org.genntii.smcommon.exception.UserNotFoundException;
import org.genntii.smcommon.result.PageResult;
import org.genntii.smcommon.utils.AliOssUtil;
import org.genntii.smcommon.utils.DateUtil;
import org.genntii.smdomain.dto.CommentDTO;
import org.genntii.smdomain.entity.Comment;
import org.genntii.smdomain.entity.CommentImage;
import org.genntii.smdomain.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.tlipoca.smcomment.client.ArticleClient;
import org.tlipoca.smcomment.client.CommentImageClient;
import org.tlipoca.smcomment.client.CommentLikeClient;
import org.tlipoca.smcomment.client.UserClient;
import org.tlipoca.smcomment.mapper.CommentMapper;
import org.tlipoca.smcomment.service.CommentService;

import java.io.IOException;
import java.util.*;

@Slf4j
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Resource
    private CommentMapper commentMapper;

    @Resource
    private ArticleClient articleClient;

    @Resource
    private UserClient userClient;

    @Resource
    private CommentImageClient commentImageClient;

    @Resource
    private AliOssUtil aliOssUtil;

    @Resource
    private CommentLikeClient commentLikeClient;

    @Override
    public Long getCommentTotalByUserId(Long userId){
        return commentMapper.getCommentTotalByUserId(userId);
    }

    @Override
    public ArrayList<CommentClientVO> getCommentLimit(Long userId, Integer pageNum, Integer pageSize) {
        ArrayList<Comment> commentByUserLimit = commentMapper.getCommentByUserLimit(userId, (pageNum - 1) * pageSize, pageSize);
        ArrayList<CommentClientVO> commentClientVOS = new ArrayList<>();

        for (Comment comment: commentByUserLimit){
            commentClientVOS.add(CommentClientVO.builder()
                    .id(comment.getId())
                    .articleId(comment.getArticleId())
                    .userId(comment.getUserId())
                    .nickname(comment.getNickname())
                    .replyCommentId(comment.getReplyCommentId())
                    .replyUserId(comment.getReplyUserId())
                    .replyUserNickname(comment.getReplyUserNickname())
                    .content(comment.getContent())
                    .cityCode(comment.getCityCode())
                    .cityName(comment.getCityName())
                    .createTime(DateUtil.toString(comment.getCreateTime()))
                    .updateTime(DateUtil.toString(comment.getUpdateTime()))
                    .build());
        }
        return commentClientVOS;
    }

    @Override
    public ArrayList<CommentClientVO> getArticleByUserId(Long userId) {
        ArrayList<Comment> commentByUserId = commentMapper.getCommentByUserId(userId);
        ArrayList<CommentClientVO> commentClientVOS = new ArrayList<>();

        for (Comment comment : commentByUserId){
            commentClientVOS.add(CommentClientVO.builder()
                    .id(comment.getId())
                    .articleId(comment.getArticleId())
                    .userId(comment.getUserId())
                    .nickname(comment.getNickname())
                    .replyCommentId(comment.getReplyCommentId())
                    .replyUserId(comment.getReplyUserId())
                    .replyUserNickname(comment.getReplyUserNickname())
                    .content(comment.getContent())
                    .cityCode(comment.getCityCode())
                    .cityName(comment.getCityName())
                    .createTime(DateUtil.toString(comment.getCreateTime()))
                    .updateTime(DateUtil.toString(comment.getUpdateTime()))
                    .build());
        }
        return commentClientVOS;
    }

    @Override
    public Integer getCommentCount(Long articleId) {
        return commentMapper.getArticleCommentCount(articleId);
    }

    @Override
    public Boolean getCommentExistsService(Long commentId) {
        return commentMapper.selectById(commentId)!=null;
    }

    @Override
    public PageResult<CommentDetailVO> getCommentListByArticleIdService(Long articleId, Integer pageNum, Integer pageSize,Long userId) {
//        // 判断文章是否存在
//        if (!articleClient.getArticleExists(articleId).getData()) {
//            throw new ArticleNotFoundException(ExceptionConstant.ARTICLE_NOT_FOUND_EXCEPTION);
//        }

        // 根据文章Id查询评论
        ArrayList<Comment> commentList = commentMapper.selectCommentListByArticleId(articleId,(pageNum - 1)*pageSize,pageSize);
        if (commentList.isEmpty()){
            return PageResult.build(new ArrayList<>(),0);
        }

        // 根据评论Id查询图片
        ArrayList<CommentDetailVO> commentVOList = new ArrayList<>();
        ArrayList<Long> commentIds = new ArrayList<>();

//        批量查找用户
        ArrayList<Long> userIds = new ArrayList<>();
        for (Comment comment:commentList){
            userIds.add(comment.getUserId());
        }
//        ArrayList<UserVO> userVOS =//TODO 批量查找用户
        Map<Long, UserVO> userIdUserVOSMap = new HashMap<>();
        for (Comment comment : commentList) {
            UserVO userVO = userClient.getUserById(comment.getUserId()).getData();
            LikeVO likeVO = commentLikeClient.getCommentLIkeVO(comment.getId(),userId).getData();
            CommentDetailVO commentDetailVO = CommentDetailVO.builder()
                    .id(comment.getId())
                    .articleId(comment.getArticleId())
                    .userId(comment.getUserId())
                    .nickname(userVO.getNickname())
                    .avatar(userVO.getAvatar())
                    .content(comment.getContent())
                    .cityName(comment.getCityName())
                    .createTime(comment.getCreateTime())
                    .replyCount(commentMapper.getReplyCount(comment.getId()))
                    .build();
            if (likeVO != null){
                commentDetailVO.setLike(likeVO.getLike());
                commentDetailVO.setDislike(likeVO.getDislike());
                commentDetailVO.setLiked(likeVO.getLiked());
            }
            commentVOList.add(commentDetailVO);
            commentIds.add(comment.getId());
        }

        // 遍历VOList 若replyCounts 不为零 查找其最热三条评论VO
        for (CommentDetailVO commentDetailVO:commentVOList){
            if (commentDetailVO.getReplyCount() == 0) continue;
            ArrayList<Comment> reply3 = commentMapper.get3Reply(commentDetailVO.getId());
            ArrayList<CommentReplyVO> commentReplyVOS = new ArrayList<>();
            for (Comment comment : reply3){
                LikeVO likeVO = commentLikeClient.getCommentLIkeVO(comment.getId(),comment.getUserId()).getData();
                commentReplyVOS.add(CommentReplyVO.builder()
                        .id(comment.getId())
                        .articleId(comment.getArticleId())
                        .userId(comment.getUserId())
                        .nickname(comment.getNickname())
                        .avatar(userClient.getUserById(comment.getUserId()).getData().getAvatar())
                        .replyUserNickname(comment.getReplyUserNickname())
                        .cityName(comment.getCityName())
                        .content(comment.getContent())
                        .like(likeVO.getLike())
                        .dislike(likeVO.getDislike())
                        .liked(likeVO.getLiked())
                        .replyCommentId(commentDetailVO.getId())
                        .replyUserId(comment.getReplyUserId())
                        .createTime(comment.getCreateTime())
                        .build());
            }
            commentDetailVO.setVisibleReply(commentReplyVOS);

        }

        HashMap<Long, ArrayList<CommentImage>> commentImageMap = commentImageClient.getCommentImageGroupByCommentIdList(commentIds).getData();
        for (CommentDetailVO commentDetailVO: commentVOList) {
            // 判断评论是否存在图片
            if (commentImageMap.get(commentDetailVO.getId()) != null) {
                // 评论存在图片
                commentDetailVO.setCommentImage(commentImageMap.get(commentDetailVO.getId()));
            }
        }

        long total = commentMapper.selectCommentTotalByArticleId(articleId);
        return PageResult.build(commentVOList,total);
    }

    @Override
    public ArrayList<CommentReplyVO> getAllReply(Long commentId,Long userId) {
        ArrayList<Comment> comments = commentMapper.getAllReply(commentId);
        ArrayList<CommentReplyVO> commentReplyVOS = new ArrayList<>();
        for (Comment comment:comments){
            LikeVO likeVO = commentLikeClient.getCommentLIkeVO(comment.getId(),userId).getData();
            commentReplyVOS.add(CommentReplyVO.builder()
                    .id(comment.getId())
                    .articleId(comment.getArticleId())
                    .replyUserId(comment.getArticleId())
                    .userId(comment.getUserId())
                    .replyCommentId(commentId)
                    .replyUserId(comment.getReplyUserId())
                    .nickname(comment.getNickname())
                    .replyUserNickname(comment.getReplyUserNickname())
                    .avatar(userClient.getUserById(comment.getUserId()).getData().getAvatar())
                    .content(comment.getContent())
                    .cityName(comment.getCityName())
                    .createTime(comment.getCreateTime())
                    .like(likeVO.getLike())
                    .dislike(likeVO.getDislike())
                    .liked(likeVO.getLiked())
                    .build());

        }
        return commentReplyVOS;
    }

    @Override
    public ArrayList<CommentVO> getCommentTreeService(Long articleId, Long userId) {
        // TODO. 评论回复树实现
        return null;
    }

    @Override
    public void addCommentService(CommentDTO commentDTO,Long userId,Long replyCommentId) {
        // 判断文章是否存在
//        if (!articleClient.getArticleExists(commentDTO.getArticleId()).getData()) {
//            throw new ArticleNotFoundException(ExceptionConstant.ARTICLE_NOT_FOUND_EXCEPTION);
//        }

//        // 判断新增回复 / 评论
//        if (commentDTO.getReplyUserId() != null) {
//            // 回复
//            // 判断回复用户Id是否存在
//            if (!userClient.getUserExists(commentDTO.getReplyUserId()).getData()) {
//                throw new UserNotFoundException(ExceptionConstant.USER_NOT_FOUND_EXCEPTION);
//            }
//        }

        // 插入数据库
        Comment comment = new Comment();
        BeanUtils.copyProperties(commentDTO, comment);
        comment.setUserId(userId);
        comment.setArticleId(commentDTO.getArticleId());
        if (replyCommentId != null){
            comment.setReplyUserNickname(userClient.getUserById(commentDTO.getReplyUserId()).getData().getNickname());
        }
        comment.setNickname(userClient.getUserById(userId).getData().getNickname());

        commentMapper.insert(comment);

        // 判断评论是否存在图片
        if (commentDTO.getCommentImages() != null && !commentDTO.getCommentImages().isEmpty()) {
            // 评论存在图片
            // 插入评论图片数据库
            commentImageClient.addCommentImage(commentDTO.getCommentImages());
        }



    }

    @Override
    public void deleteComment(Long commentId) {
        // 判断评论是否存在
        if (!commentMapper.exists(new QueryWrapper<Comment>().eq("id", commentId))) {
            throw new CommentNotFoundException(ExceptionConstant.COMMENT_NOT_FOUND_EXCEPTION);
        }

        // 删除评论图片
        commentImageClient.deleteCommentImageByCommentId(commentId);

        // 删除评论
        commentMapper.deleteById(commentId);

    }

    @Override
    public Map<Integer, String> picBatchUpload(MultipartFile[] files) {
        Map<Integer, String> urls = new HashMap<>();
        List<MultipartFile> fileList = Arrays.asList(files);
        for (MultipartFile file:fileList){
            try {
                urls.put(fileList.indexOf(file), aliOssUtil.upload(file.getBytes(), file.getOriginalFilename()));
            } catch (IOException e){
                throw new RuntimeException(e+"上传失败");
            }
        }
        return urls;
    }

    @Override
    public String picUpload(MultipartFile file) {
        String url;
        try {
            url = aliOssUtil.upload(file.getBytes(),file.getOriginalFilename());
        } catch (IOException e) {
            throw new RuntimeException(e+"上传失败");
        }
        return url;
    }

    @Override
    public CommentReplyVO getCommentReply(Long commentId, Long userId) {
        Comment comment = commentMapper.selectById(commentId);
        LikeVO likeVO = commentLikeClient.getCommentLIkeVO(comment.getId(), comment.getUserId()).getData();
        CommentReplyVO commentReplyVO = CommentReplyVO.builder()
                .id(comment.getId())
                .articleId(comment.getArticleId())
                .userId(comment.getUserId())
                .nickname(comment.getNickname())
                .avatar(userClient.getUserById(comment.getUserId()).getData().getAvatar())
                .cityName(comment.getCityName())
                .content(comment.getContent())
                .like(likeVO.getLike())
                .dislike(likeVO.getDislike())
                .liked(likeVO.getLiked())
                .replyCommentId(comment.getReplyCommentId())
                .replyUserId(comment.getReplyUserId())
                .createTime(comment.getCreateTime())
                .build();
        return commentReplyVO;
    }

    @Override
    public CommentDetailVO getCommentDetail(Long commentId, Long userId) {
        Comment comment = commentMapper.selectById(commentId);
        LikeVO likeVO = commentLikeClient.getCommentLIkeVO(comment.getId(),userId).getData() ;
        UserVO userVO = userClient.getUserById(comment.getUserId()).getData();
        CommentDetailVO commentDetailVO = CommentDetailVO.builder()
                .id(comment.getId())
                .articleId(comment.getArticleId())
                .userId(comment.getUserId())
                .nickname(userVO.getNickname())
                .avatar(userVO.getAvatar())
                .content(comment.getContent())
                .cityName(comment.getCityName())
                .createTime(comment.getCreateTime())
                .replyCount(commentMapper.getReplyCount(comment.getId()))
                .build();
        if (likeVO != null){
            commentDetailVO.setLike(likeVO.getLike());
            commentDetailVO.setDislike(likeVO.getDislike());
            commentDetailVO.setLiked(likeVO.getLiked());
        }
        return commentDetailVO;
    }
}
